home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1991-02-16  |  24KB  |  885 lines

  1. /*
  2.  * The functions in this file handle redisplay. The
  3.  * redisplay system knows almost nothing about the editing
  4.  * process; the editing functions do, however, set some
  5.  * hints to eliminate a lot of the grinding. There is more
  6.  * that can be done; the "vtputc" interface is a real
  7.  * pig. Two conditional compilation flags; the GOSLING
  8.  * flag enables dynamic programming redisplay, using the
  9.  * algorithm published by Jim Gosling in SIGOA. The MEMMAP
  10.  * changes things around for memory mapped video. With
  11.  * both off, the terminal is a VT52.
  12.  */
  13. #include    "def.h"
  14. #include    "kbd.h"
  15.  
  16. /*
  17.  * You can change these back to the types
  18.  * implied by the name if you get tight for space. If you
  19.  * make both of them "int" you get better code on the VAX.
  20.  * They do nothing if this is not Gosling redisplay, except
  21.  * for change the size of a structure that isn't used.
  22.  * A bit of a cheat.
  23.  */
  24. /* These defines really belong in sysdef.h */
  25. #ifndef XCHAR
  26. #  define    XCHAR    int
  27. #  define    XSHORT    int
  28. #endif
  29.  
  30. #ifdef    STANDOUT_GLITCH
  31. extern int SG;                /* number of standout glitches    */
  32. #endif
  33.  
  34. /*
  35.  * A video structure always holds
  36.  * an array of characters whose length is equal to
  37.  * the longest line possible. Only some of this is
  38.  * used if "ncol" isn't the same as "NCOL".
  39.  */
  40. typedef struct    {
  41.     short    v_hash;            /* Hash code, for compares.    */
  42.     short    v_flag;            /* Flag word.            */
  43.     short    v_color;        /* Color of the line.        */
  44.     XSHORT    v_cost;            /* Cost of display.        */
  45.     char    v_text[NCOL];        /* The actual characters.    */
  46. }    VIDEO;
  47.  
  48. #define VFCHG    0x0001            /* Changed.            */
  49. #define VFHBAD    0x0002            /* Hash and cost are bad.    */
  50. #define VFEXT    0x0004            /* extended line (beond ncol)    */
  51.  
  52. /*
  53.  * SCORE structures hold the optimal
  54.  * trace trajectory, and the cost of redisplay, when
  55.  * the dynamic programming redisplay code is used.
  56.  * If no fancy redisplay, this isn't used. The trace index
  57.  * fields can be "char", and the score a "short", but
  58.  * this makes the code worse on the VAX.
  59.  */
  60. typedef struct    {
  61.     XCHAR    s_itrace;        /* "i" index for track back.    */
  62.     XCHAR    s_jtrace;        /* "j" index for trace back.    */
  63.     XSHORT    s_cost;            /* Display cost.        */
  64. }    SCORE;
  65.  
  66. int    sgarbf    = TRUE;            /* TRUE if screen is garbage.    */
  67. int    vtrow    = 0;            /* Virtual cursor row.        */
  68. int    vtcol    = 0;            /* Virtual cursor column.    */
  69. int    tthue    = CNONE;        /* Current color.        */
  70. int    ttrow    = HUGE;            /* Physical cursor row.        */
  71. int    ttcol    = HUGE;            /* Physical cursor column.    */
  72. int    tttop    = HUGE;            /* Top of scroll region.    */
  73. int    ttbot    = HUGE;            /* Bottom of scroll region.    */
  74. int    lbound    = 0;            /* leftmost bound of the current line */
  75.                     /* being displayed        */
  76.  
  77. VIDEO    *vscreen[NROW-1];        /* Edge vector, virtual.    */
  78. VIDEO    *pscreen[NROW-1];        /* Edge vector, physical.    */
  79. VIDEO    video[2*(NROW-1)];        /* Actual screen data.        */
  80. VIDEO    blanks;                /* Blank line image.        */
  81.  
  82. /*
  83.  * Some predeclerations to make ANSI compilers happy
  84.  */
  85. VOID    vtinit();
  86. VOID    vttidy();
  87. VOID    vtmove();
  88. VOID    vtputc();
  89. VOID    vtpute();
  90. VOID    vteeol();
  91. VOID    update();
  92. VOID    updext();
  93. VOID    ucopy();
  94. VOID    uline();
  95. VOID    modeline();
  96. VOID    hash();
  97. VOID    setscores();
  98. VOID    traceback();
  99.  
  100. #ifdef    GOSLING
  101. /*
  102.  * This matrix is written as an array because
  103.  * we do funny things in the "setscores" routine, which
  104.  * is very compute intensive, to make the subscripts go away.
  105.  * It would be "SCORE    score[NROW][NROW]" in old speak.
  106.  * Look at "setscores" to understand what is up.
  107.  */
  108. SCORE    score[NROW*NROW];
  109. #endif
  110.  
  111. /*
  112.  * Initialize the data structures used
  113.  * by the display code. The edge vectors used
  114.  * to access the screens are set up. The operating
  115.  * system's terminal I/O channel is set up. Fill the
  116.  * "blanks" array with ASCII blanks. The rest is done
  117.  * at compile time. The original window is marked
  118.  * as needing full update, and the physical screen
  119.  * is marked as garbage, so all the right stuff happens
  120.  * on the first call to redisplay.
  121.  */
  122. VOID
  123. vtinit() {
  124.     register VIDEO    *vp;
  125.     register int    i;
  126.  
  127.     ttopen();
  128.     ttinit();
  129.     vp = &video[0];
  130.     for (i=0; i<NROW-1; ++i) {
  131.         vscreen[i] = vp;
  132.         ++vp;
  133.         pscreen[i] = vp;
  134.         ++vp;
  135.     }
  136.     blanks.v_color = CTEXT;
  137.     for (i=0; i<NCOL; ++i)
  138.         blanks.v_text[i] = ' ';
  139. }
  140.  
  141. /*
  142.  * Tidy up the virtual display system
  143.  * in anticipation of a return back to the host
  144.  * operating system. Right now all we do is position
  145.  * the cursor to the last line, erase the line, and
  146.  * close the terminal channel.
  147.  */
  148. VOID
  149. vttidy() {
  150.     ttcolor(CTEXT);
  151.     ttnowindow();                /* No scroll window.    */
  152.     ttmove(nrow-1, 0);            /* Echo line.        */
  153.     tteeol();
  154.     tttidy();
  155.     ttflush();
  156.     ttclose();
  157. }
  158.  
  159. /*
  160.  * Move the virtual cursor to an origin
  161.  * 0 spot on the virtual display screen. I could
  162.  * store the column as a character pointer to the spot
  163.  * on the line, which would make "vtputc" a little bit
  164.  * more efficient. No checking for errors.
  165.  */
  166. VOID
  167. vtmove(row, col) {
  168.     vtrow = row;
  169.     vtcol = col;
  170. }
  171.  
  172. /*
  173.  * Write a character to the virtual display,
  174.  * dealing with long lines and the display of unprintable
  175.  * things like control characters. Also expand tabs every 8
  176.  * columns. This code only puts printing characters into
  177.  * the virtual display image. Special care must be taken when
  178.  * expanding tabs. On a screen whose width is not a multiple
  179.  * of 8, it is possible for the virtual cursor to hit the
  180.  * right margin before the next tab stop is reached. This
  181.  * makes the tab code loop if you are not careful.
  182.  * Three guesses how we found this.
  183.  */
  184. VOID
  185. vtputc(c) register int c; {
  186.     register VIDEO    *vp;
  187.  
  188.     vp = vscreen[vtrow];
  189.     if (vtcol >= ncol)
  190.         vp->v_text[ncol-1] = '$';
  191.     else if (c == '\t'
  192. #ifdef    NOTAB
  193.         && !(curbp->b_flag & BFNOTAB)
  194. #endif
  195.         ) {
  196.         do {
  197.             vtputc(' ');
  198.         } while (vtcol<ncol && (vtcol&0x07)!=0);
  199.     } else if (ISCTRL(c)) {
  200.         vtputc('^');
  201.         vtputc(CCHR(c));
  202.     } else
  203.         vp->v_text[vtcol++] = c;
  204. }
  205.  
  206. /* Put a character to the virtual screen in an extended line.  If we are
  207.  * not yet on left edge, don't print it yet.  Check for overflow on
  208.  * the right margin.
  209.  */
  210. VOID
  211. vtpute(c)
  212. int c;
  213. {
  214.     register VIDEO    *vp;
  215.  
  216.     vp = vscreen[vtrow];
  217.  
  218.     if (vtcol >= ncol) vp->v_text[ncol - 1] = '$';
  219.     else if (c == '\t'
  220. #ifdef    NOTAB
  221.                && !(curbp->b_flag & BFNOTAB)
  222. #endif
  223.                       ) {
  224.     do {
  225.         vtpute(' ');
  226.     }
  227.     while (((vtcol + lbound)&0x07) != 0 && vtcol < ncol);
  228.     } else if (ISCTRL(c) != FALSE) {
  229.     vtpute('^');
  230.     vtpute(CCHR(c));
  231.     } else {
  232.     if (vtcol >= 0) vp->v_text[vtcol] = c;
  233.     ++vtcol;
  234.     }
  235. }
  236.  
  237. /* Erase from the end of the
  238.  * software cursor to the end of the
  239.  * line on which the software cursor is
  240.  * located. The display routines will decide
  241.  * if a hardware erase to end of line command
  242.  * should be used to display this.
  243.  */
  244. VOID
  245. vteeol() {
  246.     register VIDEO    *vp;
  247.  
  248.     vp = vscreen[vtrow];
  249.     while (vtcol < ncol)
  250.         vp->v_text[vtcol++] = ' ';
  251. }
  252.  
  253. /*
  254.  * Make sure that the display is
  255.  * right. This is a three part process. First,
  256.  * scan through all of the windows looking for dirty
  257.  * ones. Check the framing, and refresh the screen.
  258.  * Second, make sure that "currow" and "curcol" are
  259.  * correct for the current window. Third, make the
  260.  * virtual and physical screens the same.
  261.  */
  262. VOID
  263. update() {
  264.     register LINE    *lp;
  265.     register WINDOW *wp;
  266.     register VIDEO    *vp1;
  267.     VIDEO        *vp2;
  268.     register int    i;
  269.     register int    j;
  270.     register int    c;
  271.     register int    hflag;
  272.     register int    currow;
  273.     register int    curcol;
  274.     register int    offs;
  275.     register int    size;
  276.     VOID traceback ();
  277.     VOID uline ();
  278.  
  279.     if (typeahead()) return;
  280.     if (sgarbf) {                /* must update everything */
  281.         wp = wheadp;
  282.         while(wp != NULL) {
  283.             wp->w_flag |= WFMODE | WFHARD;
  284.             wp = wp->w_wndp;
  285.         }
  286.     }
  287.     hflag = FALSE;                /* Not hard.        */
  288.     wp = wheadp;
  289.     while (wp != NULL) {
  290.         if (wp->w_flag != 0) {        /* Need update.        */
  291.             if ((wp->w_flag&WFFORCE) == 0) {
  292.                 lp = wp->w_linep;
  293.                 for (i=0; i<wp->w_ntrows; ++i) {
  294.                     if (lp == wp->w_dotp)
  295.                         goto out;
  296.                     if (lp == wp->w_bufp->b_linep)
  297.                         break;
  298.                     lp = lforw(lp);
  299.                 }
  300.             }
  301.             i = wp->w_force;    /* Reframe this one.    */
  302.             if (i > 0) {
  303.                 --i;
  304.                 if (i >